package com.bestcem.xm.user.grpc.client;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.bestcem.xm.common.core.constant.GrpcClientNames;
import com.bestcem.xm.common.core.domain.web.ServiceResult;
import com.bestcem.xm.common.core.enums.ResourceErrorCodeEnum;
import com.bestcem.xm.om.grpc.v1.services.*;
import com.bestcem.xm.user.enums.PackageTypeEnum;
import com.bestcem.xm.user.grpc.client.convert.PackageGrpcConvert;
import com.bestcem.xm.user.grpc.client.dto.PackageDTO;
import com.zy.dp.proto.base.v1.Code;
import lombok.extern.slf4j.Slf4j;
import net.devh.boot.grpc.client.inject.GrpcClient;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Nullable;
import javax.annotation.Resource;
import java.util.Objects;

/**
 * 套餐 grpc service
 *
 * @author wangyunyun <yunyun.wang@idiaoyan.com>
 * @version v1.0
 * @date 2022/3/10 14:56
 */
@Slf4j
@Service("userPackageGrpcService")
public class PackageGrpcService {

    @GrpcClient(GrpcClientNames.DS_USER)
    private PackageServiceGrpc.PackageServiceBlockingStub packServiceBlockingStub;

    @Resource
    private PackageGrpcConvert packageGrpcConvert;

    /**
     * 通过套餐类型获取套餐信息
     *
     * @param type
     * @return PackageDTO
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @version v1.0
     * @date 2022/3/10 17:19
     */
    @Nullable
    public PackageDTO getByType(Integer type) {
        GetPackageByTypeRequest.Builder builder = GetPackageByTypeRequest.newBuilder();
        builder.setTypeValue(type);
        try {
            GetPackageByTypeResponse response = packServiceBlockingStub.getPackageByType(builder.build());
            if (Objects.isNull(response) || Code.ERROR_VALUE == response.getStatus().getCodeValue()) {
                log.error("[PACKAGE] PACKAGE GetPackageByType {} Error; ErrorMsg: {}", type, response);
                return null;
            }
            return packageGrpcConvert.packGrpc2Dto(response.getPackage());
        } catch (Exception e) {
            log.error("[PACKAGE] PACKAGE GetPackageByType {} Error; ErrorMsg: {}", type, e.getMessage(), e);
            return null;
        }
    }

    /**
     * 通过套餐类型获取套餐信息
     *
     * @param type
     * @return ServiceResult<PackageDTO>
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @date 2022/6/18 18:52
     */
    public ServiceResult<PackageDTO> getByTypeByBusiness(Integer type) {
        PackageDTO packageDTO = this.getByType(type);
        if (packageDTO == null) {
            return ServiceResult.fail(null, String.format("Pack[ttype={%s}] is not found", PackageTypeEnum.FREE_TRIAL.getType()),
                    String.valueOf(ResourceErrorCodeEnum.NOT_FOUND.getCode()));
        }

        return ServiceResult.success(packageDTO);
    }

    /**
     * 通过套餐id查询套餐信息
     *
     * @param id 套餐id
     * @return com.bestcem.xm.user.grpc.client.dto.PackageDTO
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/03/21 16:52
     */
    @Nullable
    public PackageDTO getById(String id) {
        GetPackageByIdRequest.Builder builder = GetPackageByIdRequest.newBuilder();
        builder.setId(id);
        try {
            GetPackageByIdResponse response = packServiceBlockingStub.getPackageById(builder.build());
            if (Objects.isNull(response) || Code.ERROR_VALUE == response.getStatus().getCodeValue()) {
                log.error("[PACKAGE] PACKAGE getById {} Error; ErrorMsg: {}", id, response);
                return new PackageDTO();
            }
            return packageGrpcConvert.packGrpc2Dto(response.getPackage());
        } catch (Exception e) {
            log.error("[PACKAGE] PACKAGE getById {} Error; ErrorMsg: {}", id, e.getMessage(), e);
            return new PackageDTO();
        }
    }

    /**
     * 判断套餐是否含有客户旅程模块
     *
     * @param packageId
     * @return Boolean
     * @author wangyunyun <yunyun.wang@idiaoyan.com>
     * @version v1.0
     * @date 2022/3/16 14:04
     */
    @Nullable
    public Boolean hasCustomerJourneyModule(String packageId) {
        HasCustomerJourneyModuleRequest.Builder builder = HasCustomerJourneyModuleRequest.newBuilder();
        builder.setId(packageId);
        try {
            HasCustomerJourneyModuleResponse response = packServiceBlockingStub.hasCustomerJourneyModule(builder.build());
            if (Objects.isNull(response) || Code.ERROR_VALUE == response.getStatus().getCodeValue()) {
                log.error("[PACKAGE] PACKAGE hasCustomerJourneyModule {} Error; ErrorMsg: {}", packageId, response);
                return Boolean.FALSE;
            }
            return response.getContain();
        } catch (Exception e) {
            log.error("[PACKAGE] PACKAGE hasCustomerJourneyModule {} Error; ErrorMsg: {}", packageId, e.getMessage(), e);
            return Boolean.FALSE;
        }


    }


    /**
     * 通过套餐名称和类型查询
     *
     * @param name 套餐name
     * @return com.bestcem.xm.user.grpc.client.dto.PackageDTO
     * @author Linzhijian <qiongyu.cui@idiaoyan.cn>
     * @date 2022/03/21 16:52
     */
    public PackageDTO getByNameAndType(String name, Integer type) {
        GetPackageByNameAndTypeRequest.Builder builder = GetPackageByNameAndTypeRequest.newBuilder();
        builder.setName(name);
        builder.setTypeValue(type);
        try {
            GetPackageByNameAndTypeResponse response = packServiceBlockingStub.getPackageByNameAndType(builder.build());
            if (Objects.isNull(response) || Code.ERROR_VALUE == response.getStatus().getCodeValue()) {
                log.error("[PACKAGE] PACKAGE getByNameAndType {} Error; ErrorMsg: {}", type, response);
                return null;
            }
            return packageGrpcConvert.packGrpc2Dto(response.getPackage());
        } catch (Exception e) {
            log.error("[PACKAGE] PACKAGE getByNameAndType {} Error; ErrorMsg: {}", type, e.getMessage(), e);
            return null;
        }

    }

    /**
     * 根据组织id或者packageId查询套餐相关限额信息
     *
     * @param packageId 套餐id
     * @param orgId     租户id
     * @return com.alibaba.fastjson.JSONObject 套餐相关限额信息的json格式
     * @author cuiqiongyu <qiongyu.cui@idiaoyan.cn>
     * @date 2022/07/02 21:17
     */
    public JSONObject getPackageQuota(String packageId, String orgId) {
        if (log.isInfoEnabled()) {
            log.info("根据组织id或者packageId查询套餐相关限额信息：packageId:{}，orgId:{}", packageId, orgId);
        }

        // 参数校验
        if (StringUtils.isEmpty(packageId) && StringUtils.isEmpty(orgId)) {
            log.error("根据组织id或者packageId查询套餐相关限额信息失败，packageId和orgId不能都为空！");
            return new JSONObject();
        }

        GetPackageQuotaRequest.Builder builder = GetPackageQuotaRequest.newBuilder();
        if (Objects.nonNull(packageId)) {
            builder.setId(packageId);
        }
        if (Objects.nonNull(orgId)) {
            builder.setOrgId(orgId);
        }

        // 请求套餐服务
        GetPackageQuotaResponse packageQuota = packServiceBlockingStub.getPackageQuota(builder.build());
        // 校验查询结果
        if (Code.ERROR_VALUE == packageQuota.getStatus().getCodeValue()) {
            log.error("根据组织id或者packageId查询套餐相关限额信息失败：packageId:{} orgId:{}", packageQuota.getStatus().getMessage(), packageId, orgId);
            return new JSONObject();
        }

        String quota = packageQuota.getQuota();
        return JSON.parseObject(quota);
    }


    /**
     * 升级套餐
     *
     * @param orderNo
     * @return com.bestcem.xm.user.grpc.client.dto.OmUserDTO
     * @author Linzhijian <zhijian.lin@idiaoyan.com>
     * @date 2022/07/7 09:40
     */
    public void upgradePackage(String orderNo) {
        UpgradePackageRequest request = UpgradePackageRequest.newBuilder().setOrderNo(orderNo).build();
        UpgradePackageResponse response = packServiceBlockingStub.upgradePackage(request);
        // 校验查询结果
        if (Code.ERROR_VALUE == response.getStatus().getCodeValue()) {
            log.error("【USER】升级套餐失败 orderNo:{} dto:{}", orderNo, response.getStatus().getMessage());
        }
    }

    /**
     * 删除套餐缓存
     *
     * @param orgId
     */
    public void deletePackageCacheByOrgId(String orgId) {
        if (StringUtils.isBlank(orgId)) {
            log.error("【USER】删除套餐缓存失败，缺少orgId");
            return;
        }
        DeletePackageCacheByOrgIdRequest request = DeletePackageCacheByOrgIdRequest.newBuilder().setOrgId(orgId).build();
        DeletePackageCacheByOrgIdResponse response = packServiceBlockingStub.deletePackageCacheByOrgId(request);
        // 校验查询结果
        if (Code.ERROR_VALUE == response.getStatus().getCodeValue()) {
            log.error("【USER】升级套餐失败 删除套餐缓存失败:{} orgId:{},dto={}", orgId, response.getStatus().getMessage());
        }
    }
}
